import { regeo } from '@/dataTransfer/address';
import Taro from '@tarojs/taro';
import utils from '@/utils/index';

export const LAST_ADDRESS_STORE_KEY = 'lastAddressId';

export const AddressType = {
  last: 'lastLocation',
  default: 'defaultLocation',
  // 微信定位或网页定位
  gps: 'gpsLocation',
  ip: 'ipLocation',
  failed: 'failed',
};

// 存在 id(即用户存在的地址) 或者 存在 adcode (即通过 行政区域编码转换)
const wrapType = (result, type) => {
  if (result?.id || result?.adcode) {
    return {
      ...result,
      type,
    };
  }

  return;
};

// 经纬度转行政编码
const latlng2address = (() => {
  const cache = {};

  return async ({ latitude, longitude } = {}) => {
    if (!latitude || !longitude) {
      return;
    }

    const key = `${latitude}|${longitude}`;

    if (cache[key]) {
      return cache[key];
    }

    const result = await regeo({ latitude, longitude });
    cache[key] = result;

    return cache[key];
  };
})();

// 获取上次使用地址
const getLastLocation = async (allAddresses) => {
  // 没有地址列表, 说明无法匹配上次选择地址, 直接返回
  if (!allAddresses.length) {
    return;
  }

  const { data: addressId } = await Taro.getStorage({ key: LAST_ADDRESS_STORE_KEY }).catch(() => {
    return {};
  });

  if (!addressId) {
    return;
  }

  const temp = allAddresses.find(({ id }) => {
    return id === addressId;
  });

  return wrapType(temp, AddressType.last);
};

// 获取默认地址
const getDefaultLocation = async (allAddresses) => {
  // 默认地址排在第一个
  const temp = allAddresses[0];

  return wrapType(temp, AddressType.default);
};

// 获取IP地址
const getIpLocation = (() => {
  return;
  let cache;

  // 缓存失效时间长度
  const CACHE_GAP = 10 * 60 * 1000;

  return async (_, dispatch) => {
    // 上次缓存可以使用, 直接返回缓存
    if (cache?.timeStamp && Date.now() - cache.timeStamp <= CACHE_GAP) {
      return cache;
    }

    // 获取 IP 定位
    const content = await dispatch({ type: 'otherApi/getLocationByIPModel' });

    // 获取 行政区域编码
    const addr = await latlng2address(content);

    // 加入缓存
    cache = wrapType(
      {
        timeStamp: Date.now(),
        ...content,
        ...addr,
      },
      AddressType.ip,
    );

    return cache;
  };
})();

// 小程序/浏览器定位
const getGPSLocation = async () => {
  return;
  // 获取 storage 中存储的位置
  let content = utils.getLocalEffectLocation();

  if (!content) {
    // gps 定位
    content = await Taro.getLocation({
      type: 'gcj02',
      isHighAccuracy: true,
      timeout: 3000,
    });

    // 加入 storage
    const timeStamp = new Date().getTime();
    utils.setLocalStorage('location', { ...content, timeStamp });
  }

  // 获取 行政区域编码
  const addr = await latlng2address(content);

  return wrapType(
    {
      ...content,
      ...addr,
    },
    AddressType.gps,
  );
};

// 获取 地址, 上一次选择 => 默认地址 => gps地址 => Ip地址
const getLocation = async (dispatch, allAddresses) => {
  if (!allAddresses) {
    return;
  }

  const arr = [getLastLocation, getDefaultLocation, getGPSLocation, getIpLocation];

  let temp;
  for (let i = 0; i < arr.length; i += 1) {
    temp = await arr[i](allAddresses, dispatch).catch((e) => {
      console.warn(e, { i });
      return;
    });

    if (temp) {
      break;
    }
  }

  return temp;
};

// 地址添加 fullAddress
const transformAddress = (result) => {
  if (!result) {
    return;
  }

  return {
    ...result,
    fullAddress: (result.address ?? '') + (result.houseNumber ?? ''),
  };
};

// 获取商品详情页, 用户发货地址
const getGoodsDefaultSendAddress = async (dispatch, allAddresses) => {
  if (!allAddresses) {
    return;
  }

  const temp = await getLocation(dispatch, allAddresses);
  return transformAddress(temp);
};

export { getGoodsDefaultSendAddress, transformAddress };
